from django.shortcuts import render, get_object_or_404, redirect
from django.http import Http404
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.db.models.signals import post_save
from django.dispatch import receiver
from bands.models import Musician, User, Venue
from bands.admin import UserProfile
from bands.forms import VenueForm

def musician(request, musician_id):
  musician = get_object_or_404(Musician, id=musician_id)
  data = {
    'musician': musician
  }
  return render(request, 'musician.xhtml', data)

def _get_items_per_page(request):
  # Determine how many items to show per page, disallowing <1 or >50
  items_per_page = int(request.GET.get("items_per_page", 10))
  if items_per_page < 1:
      items_per_page = 10
  if items_per_page > 50:
      items_per_page = 50

  return items_per_page

def _get_page_num(request, paginator):
  # Get current page number for Pagination, using reasonable defaults
  page_num = int(request.GET.get("page", 1))

  if page_num < 1:
      page_num = 1
  elif page_num > paginator.num_pages:
      page_num = paginator.num_pages

  return page_num

   
def musicians(request):
  musicians = Musician.objects.all().order_by('last_name')
  items_per_page = _get_items_per_page(request)
  paginator = Paginator(musicians, items_per_page)
  page_num = _get_page_num(request, paginator)
  page = paginator.page(page_num)

  data = {
    'musicians': paginator.page(page_num),
    'page': page,
  }
  return render(request, 'musicians.xhtml', data)

@login_required
def restricted_page(request):
  data = {
    'title': 'Restricted Page',
    'content': '<h1>You are logged in!</h1>',
  }
  return render(request,'general.xhtml', data)

@login_required
def musician_restricted(request, musician_id):
  musician = get_object_or_404(Musician, id=musician_id)
  profile = request.user.userprofile
  allowed = False

  if profile.musician_profiles.filter(id=musician.id).exists():
    allowed = True
  else:
    # check if they are in the same band
    musician_profiles = set(profile.musician_profiles.all())
    for band in musician.band_set.all():
      band_musicians = set(band.musicians.all())
      if band_musicians.intersection(musician_profiles):
        allowed = True
        break

  if not allowed:
    raise Http404("Permission denied")
  content = f"""
    <h1>Musician Page: {musician.last_name}</h1>
    <p>First Name: {musician.first_name}</p>
    <p>Last Name: {musician.last_name}</p>
    <p>Birth Date: {musician.birth}</p>
  """
  data = {
    'title': 'Musician Restricted Page',
    'content': content,
  }
  return render(request, 'general.xhtml', data)

@receiver(post_save, sender=User)
def user_post_save(sender, **kwargs):
  # Create UserProfile object if User object is new and not loaded from fixture
  if kwargs['created'] and not kwargs['raw']:
    user = kwargs['instance']
    try:
      profile = UserProfile.objects.get(user=user)
    except UserProfile.DoesNotExist:
      UserProfile.objects.create(user=user)

@login_required
def edit_venue(request, venue_id=0):
    if venue_id != 0:
       venue = get_object_or_404(Venue, id=venue_id)
       if not request.user.userprofile.venues_controlled.filter(id=venue.id).exists():
           raise Http404("Can only edit controlled venues")

    if request.method == 'GET':
        if venue_id == 0:
            form = VenueForm()
        else:
            form = VenueForm(instance=venue)
    else:
        if venue_id == 0:
            venue = Venue.objects.create()
        form = VenueForm(request.POST, request.FILES, instance=venue)
        if form.is_valid():
            venue = form.save()
            request.user.userprofile.venues_controlled.add(venue)
            return redirect('venues')

    data = {
        'form': form
    }
    return render(request, 'edit_venue.xhtml', data)

def venues(request):
    all_venues = Venue.objects.all().order_by("name")
    profile = getattr(request.user, "userprofile", None)
    if profile:
        for venue in all_venues:
            # Mark the venue as "controlled" if the logged in user is
            # associated with the venue
            venue.controlled = profile.venues_controlled.filter(
                id=venue.id
            ).exists()
    else:
        # Anonymous user, can't be associated with the venue
        for venue in all_venues:
            venue.controlled = False

    items_per_page = _get_items_per_page(request)
    paginator = Paginator(all_venues, items_per_page)

    page_num = _get_page_num(request, paginator)

    page = paginator.page(page_num)

    data = {
        "venues": page.object_list,
        "page": page,
    }

    return render(request, "venues.xhtml", data)

